package durak.server.control;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;

import durak.common.control.GameCommand;
import durak.common.model.Cards;
import durak.common.model.GameTableState;

/**
 * ClientPlayerControl class is responsible for receiving and forwarding to
 * handle client commands to server
 **/

public class PlayerControlHuman extends PlayerControl  {

	private Socket sock;
	
	private ObjectOutputStream outStream;
	private ObjectInputStream inputStream;

	private boolean initialized = false;
	

	public PlayerControlHuman(Socket client,Game gameSession) {
		super(gameSession);
		this.sock = client;
		try {
			outStream = new ObjectOutputStream(this.sock.getOutputStream());
			inputStream = new ObjectInputStream(this.sock.getInputStream());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	@Override
	public void run() {
		GameCommand command;
		try {
			while ((command = (GameCommand) inputStream.readObject()) != null) {
				System.out.println(command.getPlayerName());
				super.getGameSession().getCommandHandler().handleReceivedMessageFromClient(this, command);
			}
		} catch (IOException e) {
			// Something wrong with the client, maybe he is dead
			//we'll simulate leave the game command
			super.getGameSession().getCommandHandler().handleReceivedMessageFromClient(this, new GameCommand(GameCommand.CommandType.C2S_QUIT));
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void attack() {
		GameCommand command = new GameCommand(GameCommand.CommandType.S2C_ATTACK);
		sendCommand(command);
	}

	public void defend(Cards cards) {
		GameCommand command = new GameCommand(GameCommand.CommandType.S2C_DEFEND, cards);
		sendCommand(command);
	}

	public void notifyGameState(GameTableState gameState) {
		GameCommand command = new GameCommand(GameCommand.CommandType.S2C_NOTIFY_STATE);
		command.setGameState(gameState);
		command.setCards(super.getPlayer().getHand());
		sendCommand(command);
	}
	
	public void notifyRoundEnded(GameTableState gameState) {
		GameCommand command = new GameCommand(GameCommand.CommandType.S2C_ROUND_FINISHED);
		command.setGameState(gameState);
		sendCommand(command);
	}
	
	public void notifyGameEnded(GameTableState gameState) {
		GameCommand command = new GameCommand(GameCommand.CommandType.S2C_GAME_FINISHED);
		command.setGameState(gameState);
		sendCommand(command);
	}

	/**
	 * @param command
	 */
	private void sendCommand(GameCommand command) {
		command.setPlayerName(getPlayer().getName());
		try {
			outStream.reset();
			outStream.writeObject(command);
		} catch (IOException e) {
			// Something wrong with the client, maybe he is dead
			//we'll simulate leave the game command
			super.getGameSession().getCommandHandler().handleReceivedMessageFromClient(this, new GameCommand(GameCommand.CommandType.C2S_QUIT));
		}
	}

	public void notifyGameTableFull() {
		GameCommand command = new GameCommand(GameCommand.CommandType.S2C_TABLE_FULL);
		sendCommand(command);
	}
	
	/**
	 * @return the initialized
	 */
	public synchronized boolean isInitialized() {
		return initialized;
	}

	/**
	 * @param initialized the initialized to set
	 */
	public synchronized void setInitialized(boolean initialized) {
		this.initialized = initialized;
	}

	}
